import java.io.*;
import java.sql.Timestamp;
import java.util.Date;

public class Logger
{
	public int peerID;
	public FileOutputStream fos;
	//public Writer writer;
	
	public Logger(int peerID) throws IOException
	{ 
		this.peerID = peerID;
		
		peerProcess.writer = new BufferedWriter(new FileWriter(new File("log_peer_" + this.peerID + ".log")));
		
		//fos = new FileOutputStream("log_peer_" + this.peerID + ".log");
	}
	
	// method that creates a log entry whenever a peer makes a TCP connection to another peer
	public void tcpConnectToLog(int peerID2)
	{
		try
		{
			// create a new file input stream for this peer's log file
			//FileOutputStream fos = new FileOutputStream("log_peer_" + peerID + ".log");
			
			// get timestamp
			Date date = new Date();
			Timestamp time = new Timestamp(date.getTime());
			
			// [Time]: Peer [peer_ID 1] makes a connection to Peer [peer_ID 2].
			String logEntry = "[" + time.toString() + "]: Peer [" + peerID + "] makes a connection to Peer [" + peerID2 + "]."; 
			
			// write the log entry
			//fos.write(logEntry.getBytes());
			peerProcess.writer.write(logEntry);
			peerProcess.writer.newLine();
			
			// flush and close the file output stream
	    	//fos.flush();
	    	//fos.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	// method that creates a log entry whenever a peer makes a TCP connection to another peer
	public void tcpConnectFromLog(int peerID2)
	{
		try
		{
			// create a new file input stream for this peer's log file
			//FileOutputStream fos = new FileOutputStream("log_peer_" + peerID + ".log");
			
			// get timestamp
			Date date = new Date();
			Timestamp time = new Timestamp(date.getTime());
			
			// [Time]: Peer [peer_ID 1] is connected from Peer [peer_ID 2].
			String logEntry = "[" + time.toString() + "]: Peer [" + peerID + "] is connected from Peer [" + peerID2 + "]."; 
			
			// write the log entry
			//fos.write(logEntry.getBytes());
			peerProcess.writer.write(logEntry);
			peerProcess.writer.newLine();
			
			// flush and close the file output stream
	    	//fos.flush();
	    	//fos.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	// method that creates a log entry whenever a peer changes its preferred neighbors
	public void changePNLog(int[] PNList)
	{
		try
		{
			// create a new file input stream for this peer's log file
			//FileOutputStream fos = new FileOutputStream("log_peer_" + peerID + ".log");
			
			// get timestamp
			Date date = new Date();
			Timestamp time = new Timestamp(date.getTime());
			
			//[Time]: Peer [peer_ID] has the preferred neighbors [preferred neighbor ID list].
			String logEntry = "[" + time.toString() + "]: Peer [" + peerID + "] has the preferred neighbors ["; 
			
			for(int i = 0; i < PNList.length-1; i++)
			{
				logEntry = logEntry + PNList[i] + ", ";
			}
			
			logEntry = logEntry + PNList[PNList.length-1] + "].";
			
			// write the log entry
			//fos.write(logEntry.getBytes());
			peerProcess.writer.write(logEntry);
			peerProcess.writer.newLine();
			
			// flush and close the file output stream
	    	//fos.flush();
	    	//fos.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	// method that creates a log entry whenever a peer changes its optimistically unchoked neighbor
	public void changeOUNLog(int OUNID)
	{
		try
		{
			// create a new file input stream for this peer's log file
			//FileOutputStream fos = new FileOutputStream("log_peer_" + peerID + ".log");
			
			// get timestamp
			Date date = new Date();
			Timestamp time = new Timestamp(date.getTime());
			
			// [Time]: Peer [peer_ID] has the optimistically unchoked neighbor [optimistically unchoked neighbor ID].
			String logEntry = "[" + time.toString() + "]: Peer [" + peerID + "] has the optimistically unchoked neighbor [" + OUNID + "]."; 
			
			// write the log entry
			//fos.write(logEntry.getBytes());
			peerProcess.writer.write(logEntry);
			peerProcess.writer.newLine();
			
			// flush and close the file output stream
	    	//fos.flush();
	    	//fos.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	// method that creates a log entry whenever a peer is unchoked be a neighbor
	public void unchokingLog(int peerID2)
	{
		try
		{
			// create a new file input stream for this peer's log file
			//FileOutputStream fos = new FileOutputStream("log_peer_" + peerID + ".log");
			
			// get timestamp
			Date date = new Date();
			Timestamp time = new Timestamp(date.getTime());
			
			// [Time]: Peer [peer_ID 1] is unchoked by [peer_ID 2].
			String logEntry = "[" + time.toString() + "]: Peer [" + peerID + "] is unchoked by [" + peerID2 + "]."; 
			
			// write the log entry
			//fos.write(logEntry.getBytes());
			peerProcess.writer.write(logEntry);
			peerProcess.writer.newLine();
			
			// flush and close the file output stream
	    	//fos.flush();
	    	//fos.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	// method that creates a log entry whenever a peer is choked by a neighbor
	public void chokingLog(int peerID2)
	{
		try
		{
			// create a new file input stream for this peer's log file
			//FileOutputStream fos = new FileOutputStream("log_peer_" + peerID + ".log");
			
			// get timestamp
			Date date = new Date();
			Timestamp time = new Timestamp(date.getTime());
			
			// [Time]: Peer [peer_ID 1] is choked by [peer_ID 2].
			String logEntry = "[" + time.toString() + "]: Peer [" + peerID + "] is choked by [" + peerID2 + "]."; 
			
			// write the log entry
			//fos.write(logEntry.getBytes());
			peerProcess.writer.write(logEntry);
			peerProcess.writer.newLine();
			
			// flush and close the file output stream
	    	//fos.flush();
	    	//fos.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}	
	}
	
	// method that creates a log entry whenever a peer receives a 'have' message
	public void haveMessageLog(int peerID2, int pieceIndex)
	{
		try
		{
			// create a new file input stream for this peer's log file
			//FileOutputStream fos = new FileOutputStream("log_peer_" + peerID + ".log");
			
			// get timestamp
			Date date = new Date();
			Timestamp time = new Timestamp(date.getTime());
			
			// [Time]: Peer [peer_ID 1] received the 'have' message from [peer_ID 2] for the piece [piece index].
			String logEntry = "[" + time.toString() + "]: Peer [" + peerID + "] received the 'have' message from [" + peerID2 + "] for the piece [" + pieceIndex + "]."; 
			
			// write the log entry
			//fos.write(logEntry.getBytes());
			peerProcess.writer.write(logEntry);
			peerProcess.writer.newLine();
			
			// flush and close the file output stream
	    	//fos.flush();
	    	//fos.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}	
	}
	
	// method that creates a log entry whenever a peer receives an 'interested' message
	public void interestedMessageLog(int peerID2)
	{
		try
		{
			// create a new file input stream for this peer's log file
			//FileOutputStream fos = new FileOutputStream("log_peer_" + peerID + ".log");
			
			// get timestamp
			Date date = new Date();
			Timestamp time = new Timestamp(date.getTime());
			
			// [Time]: Peer [peer_ID 1] received the 'interested' message from [peer_ID 2].
			String logEntry = "[" + time.toString() + "]: Peer [" + peerID + "] received the 'interested' message from [" + peerID2 + "]."; 
			
			// write the log entry
			//fos.write(logEntry.getBytes());
			peerProcess.writer.write(logEntry);
			peerProcess.writer.newLine();
			
			// flush and close the file output stream
	    	//fos.flush();
	    	//fos.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}	
	}
	
	// method that creates a log entry whenever a peer receives a 'not interested' message
	public void notInterestedMessageLog(int peerID2)
	{
		try
		{
			// create a new file input stream for this peer's log file
			//FileOutputStream fos = new FileOutputStream("log_peer_" + peerID + ".log");
			
			// get timestamp
			Date date = new Date();
			Timestamp time = new Timestamp(date.getTime());
			
			// [Time]: Peer [peer_ID 1] received the 'not interested' message from [peer_ID 2].
			String logEntry = "[" + time.toString() + "]: Peer [" + peerID + "] received the 'not interested' message from [" + peerID2 + "]."; 
			
			// write the log entry
			//fos.write(logEntry.getBytes());
			peerProcess.writer.write(logEntry);
			peerProcess.writer.newLine();
			
			// flush and close the file output stream
	    	//fos.flush();
	    	//fos.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}	
	}
	
	// method that creates a log entry whenever a peer finishes downloading a piece
	public void downloadPieceLog(int peerID2, int pieceIndex)
	{
		try
		{
			// create a new file input stream for this peer's log file
			//FileOutputStream fos = new FileOutputStream("log_peer_" + peerID + ".log");
			
			// get timestamp
			Date date = new Date();
			Timestamp time = new Timestamp(date.getTime());
			
			// [Time]: Peer [peer_ID 1] has downloaded the piece [piece index] from [peer_ID 2].
			String logEntry = "[" + time.toString() + "]: Peer [" + peerID + "] has downloaded the piece [" + pieceIndex + "] from [" + peerID2 + "]."; 
			
			// write the log entry
			//fos.write(logEntry.getBytes());
			peerProcess.writer.write(logEntry);
			peerProcess.writer.newLine();
			
			// flush and close the file output stream
	    	//fos.flush();
	    	//fos.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}	
	}
	
	// method that creates a log entry whenever a peer downloads the complete file
	public void completeDownloadLog()
	{
		try
		{
			// create a new file input stream for this peer's log file
			//FileOutputStream fos = new FileOutputStream("log_peer_" + peerID + ".log");
			
			// get timestamp
			Date date = new Date();
			Timestamp time = new Timestamp(date.getTime());
			
			// [Time]: Peer [peer_ID] has downloaded the complete file.
			String logEntry = "[" + time.toString() + "]: Peer [" + peerID + "] has downloaded the complete file."; 
			
			// write the log entry
			//fos.write(logEntry.getBytes());
			peerProcess.writer.write(logEntry);
			peerProcess.writer.newLine();
			
			// flush and close the file output stream
	    	//fos.flush();
	    	//fos.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}	
	}
}
